<?php
#+------------------------------------------------------------------
#| 我曾七次鄙视自己的灵魂:
#| 第一次,当它本可进取时，却故作谦卑；
#| 第二次,当它空虚时，用爱欲来填充；
#| 第三次,在困难和容易之间，它选择了容易；
#| 第四次,它犯了错，却借由别人也会犯错来宽慰自己；
#| 第五次,它自由软弱，却把它认为是生命的坚韧；
#| 第六次,当它鄙夷一张丑恶的嘴脸时，却不知那正是自己面具中的一副；
#| 第七次,它侧身于生活的污泥中虽不甘心，却又畏首畏尾。
#+------------------------------------------------------------------
#| Author:Janmas Cromwell <janmas-cromwell@outlook.com>
#+------------------------------------------------------------------
namespace app\common\lib;

use think\Exception;
use think\facade\Log;

/**
 * @property \Redis $redis
 */
class RedisManage
{

    protected $redis;

    public static $instance;

    /**
     * 重连失败次数
     * @var int
     */
    protected $reConnectErrorNum = 0;

    /**
     * 允许重连多少次
     * @var int
     */
    protected $allowreConnect = 3;

    public function __construct()
    {
        $this->connect();
    }

    /**
     * redis链接
     * @return bool
     * @throws Exception
     */
    protected function connect()
    {
        if (!extension_loaded('redis')) throw new \Exception('请先安装redis扩展');
        if (is_null($this->redis)) {

            $this->redis = new \Redis();
            $this->redis->connect(
                env('redis.host')
                , env('redis.port')
                , env('redis.timeout') ?? 0.00
                , env('redis.reserved') ?? null
                , env('redis.retryInterval') ?? 0
                , env('redis.readTimeout') ?? 0
            );

        }

        if (!$this->redis->isConnected()) {
            if ($this->reConnectErrorNum >= $this->allowreConnect) {
                throw new Exception('重连失败');
            }

            $this->reConnectErrorNum += 1;
            $this->connect();
        }
        return true;
    }

    public static function instance()
    {
        if (!self::$instance instanceof static) {
            self::$instance = new self;
        }

        return self::$instance;
    }

    /**
     * 获取redis链接
     * @return \Redis
     */
    public function getRedis(): \Redis
    {
        $this->ping();
        return $this->redis;
    }

    /**
     * 检测redis链接是否有效
     * @param false $reConnect 如果断线是否重连
     * @return bool
     */
    public function ping(bool $reConnect = false)
    {
        try {
            if ('+PONG' == $this->redis->ping()) return true;
        } catch (\Exception $exception) {
        }
        if ($reConnect) {
            return $this->connect();
        }
        return false;

    }
}